home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / reuse.lha / reuse / src / Relations.mi < prev    next >
Text File  |  1992-08-18  |  11KB  |  441 lines

  1. (* $Id: Relations.mi,v 1.4 1991/11/21 14:33:17 grosch rel $ *)
  2.  
  3. (* $Log: Relations.mi,v $
  4. Revision 1.4  1991/11/21  14:33:17  grosch
  5. new version of RCS on SPARC
  6.  
  7. Revision 1.3  91/06/07  12:19:57  grosch
  8. decreased bounds of flexible arrays
  9.  
  10. Revision 1.2  91/06/07  11:37:47  grosch
  11. increased bounds of flexible arrays
  12.  
  13. Revision 1.1  90/06/11  10:40:59  grosch
  14. added procedure GetCyclics
  15.  
  16. Revision 1.0  89/11/02  18:25:01  grosch
  17. Initial revision
  18.  
  19.  *)
  20.  
  21. (* Ich, Doktor Josef Grosch, Informatiker, 8.1.1988 *)
  22.  
  23. IMPLEMENTATION MODULE Relations;
  24.  
  25. FROM SYSTEM    IMPORT TSIZE;
  26. FROM IO        IMPORT tFile, ReadI, ReadC, WriteI, WriteC;
  27. FROM DynArray    IMPORT MakeArray, ReleaseArray;
  28. FROM Sets    IMPORT tSet;
  29.  
  30. IMPORT Sets;
  31.  
  32. VAR i, j    : SHORTCARD;
  33.  
  34. PROCEDURE MakeRelation    (VAR Rel: tRelation; Size1, Size2: INTEGER);
  35.    VAR ElmtCount : LONGINT;
  36.    BEGIN
  37.       Rel.Size1 := Size1;
  38.       Rel.Size2 := Size2;
  39.       ElmtCount := Size1 + 1;
  40.       MakeArray (Rel.ArrayPtr, ElmtCount, TSIZE (tSet));
  41.       FOR i := 0 TO Rel.Size1 DO
  42.      Sets.MakeSet (Rel.ArrayPtr^[i], Size2);
  43.       END;
  44.    END MakeRelation;
  45.  
  46. PROCEDURE ReleaseRelation (VAR Rel: tRelation);
  47.    VAR ElmtCount : LONGINT;
  48.    BEGIN
  49.       FOR i := 0 TO Rel.Size1 DO
  50.      Sets.ReleaseSet (Rel.ArrayPtr^[i]);
  51.       END;
  52.       ElmtCount := Rel.Size1 + 1;
  53.       ReleaseArray (Rel.ArrayPtr, ElmtCount, TSIZE (tSet));
  54.    END ReleaseRelation;
  55.  
  56. PROCEDURE Include    (VAR Rel: tRelation; e1, e2: INTEGER);
  57.    BEGIN
  58.       Sets.Include (Rel.ArrayPtr^[e1], e2);
  59.    END Include;
  60.  
  61. PROCEDURE Exclude    (VAR Rel: tRelation; e1, e2: INTEGER);
  62.    BEGIN
  63.       Sets.Exclude (Rel.ArrayPtr^[e1], e2);
  64.    END Exclude;
  65.  
  66. PROCEDURE IsElement    (e1, e2: INTEGER; Rel: tRelation): BOOLEAN;
  67.    BEGIN
  68.       RETURN Sets.IsElement (e2, Rel.ArrayPtr^[e1]);
  69.    END IsElement;
  70.  
  71. PROCEDURE IsRelated    (e1, e2: INTEGER; Rel: tRelation): BOOLEAN;
  72.    BEGIN
  73.       RETURN Sets.IsElement (e2, Rel.ArrayPtr^[e1]);
  74.    END IsRelated;
  75.  
  76. PROCEDURE IsReflexive1    (e1: INTEGER; Rel: tRelation): BOOLEAN;
  77.    BEGIN
  78.       RETURN Sets.IsElement (e1, Rel.ArrayPtr^[e1]);
  79.    END IsReflexive1;
  80.  
  81. PROCEDURE IsSymmetric1    (e1, e2: INTEGER; Rel: tRelation): BOOLEAN;
  82.    BEGIN
  83.       RETURN NOT Sets.IsElement (e2, Rel.ArrayPtr^[e1]) OR
  84.                  Sets.IsElement (e1, Rel.ArrayPtr^[e2]);
  85.    END IsSymmetric1;
  86.  
  87. PROCEDURE IsTransitive1    (e1, e2, e3: INTEGER; Rel: tRelation): BOOLEAN;
  88.    BEGIN
  89.       RETURN NOT (Sets.IsElement (e2, Rel.ArrayPtr^[e1]) AND
  90.           Sets.IsElement (e3, Rel.ArrayPtr^[e2])) OR
  91.           Sets.IsElement (e3, Rel.ArrayPtr^[e1]);
  92.    END IsTransitive1;
  93.  
  94. PROCEDURE IsReflexive    (Rel: tRelation): BOOLEAN;
  95.    BEGIN
  96.       FOR i := 0 TO Rel.Size1 DO
  97.      IF NOT Sets.IsElement (i, Rel.ArrayPtr^[i]) THEN RETURN FALSE; END;
  98.       END;
  99.       RETURN TRUE;
  100.    END IsReflexive;
  101.  
  102. VAR gRel    : tRelation;
  103.  
  104. PROCEDURE gSymmetric (e: CARDINAL): BOOLEAN;
  105.    BEGIN
  106.       RETURN Sets.IsElement (i, gRel.ArrayPtr^[e]);
  107.    END gSymmetric;
  108.  
  109. PROCEDURE IsSymmetric    (Rel: tRelation): BOOLEAN;
  110.    BEGIN
  111.       gRel := Rel;
  112.       FOR i := 0 TO Rel.Size1 DO
  113.      IF NOT Sets.Forall (Rel.ArrayPtr^[i], gSymmetric) THEN RETURN FALSE; END;
  114.       END;
  115.       RETURN TRUE;
  116.    END IsSymmetric;
  117.  
  118. PROCEDURE IsTransitive    (Rel: tRelation): BOOLEAN;
  119.    VAR r    : tRelation;
  120.    VAR Result    : BOOLEAN;
  121.    BEGIN
  122.       MakeRelation (r, Rel.Size1, Rel.Size2);
  123.       Assign (r, Rel);
  124.       Closure (r);
  125.       Result := IsEqual (r, Rel);
  126.       ReleaseRelation (r);
  127.       RETURN Result;
  128.    END IsTransitive;
  129.  
  130. PROCEDURE IsEquivalence    (Rel: tRelation): BOOLEAN;
  131.    BEGIN
  132.       RETURN IsReflexive (Rel) AND IsSymmetric (Rel) AND IsTransitive (Rel);
  133.    END IsEquivalence;
  134.  
  135. PROCEDURE HasReflexive    (Rel: tRelation): BOOLEAN;
  136.    BEGIN
  137.       FOR i := 0 TO Rel.Size1 DO
  138.          IF Sets.IsElement (i, Rel.ArrayPtr^[i]) THEN RETURN TRUE; END;
  139.       END;
  140.       RETURN FALSE;
  141.    END HasReflexive;
  142.  
  143. (*
  144. PROCEDURE IsCyclic    (Rel: tRelation): BOOLEAN;
  145.    VAR r    : tRelation;
  146.    VAR Result    : BOOLEAN;
  147.    BEGIN
  148.       MakeRelation (r, Rel.Size1, Rel.Size2);
  149.       Assign (r, Rel);
  150.       Closure (r);
  151.       Result := HasReflexive (r);
  152.       ReleaseRelation (r);
  153.       RETURN Result;
  154.    END IsCyclic;
  155. *)
  156.  
  157. TYPE PredCount        = ARRAY [0 .. 100000000] OF SHORTCARD;
  158.  
  159. VAR PredCountPtr    : POINTER TO PredCount;
  160. VAR WithoutPred        : tSet;
  161.  
  162. PROCEDURE IsCyclic    (Rel: tRelation): BOOLEAN;
  163.    VAR PredCountSize    : LONGINT;
  164.    VAR WithPred        : tSet;
  165.    VAR Result        : BOOLEAN;
  166.    BEGIN                (* cycle test for graphs *)
  167.       PredCountSize    := Rel.Size1 + 1;
  168.       MakeArray (PredCountPtr, PredCountSize, TSIZE (SHORTCARD));
  169.       Sets.MakeSet (WithoutPred, Rel.Size1);
  170.       Sets.MakeSet (WithPred, Rel.Size1);
  171.       FOR i := 0 TO Rel.Size1 DO PredCountPtr^[i] := 0; END;
  172.       FOR i := 0 TO Rel.Size1 DO
  173.      Sets.ForallDo (Rel.ArrayPtr^[i], gPredCount);
  174.       END;
  175.       FOR i := 0 TO Rel.Size1 DO
  176.          IF PredCountPtr^[i] = 0 THEN Sets.Include (WithoutPred, i); END;
  177.       END;
  178.       Sets.Complement (WithPred);
  179.       WHILE NOT Sets.IsEmpty (WithoutPred) DO
  180.          i := Sets.Extract (WithoutPred);
  181.          Sets.Exclude (WithPred, i);
  182.      Sets.ForallDo (Rel.ArrayPtr^[i], gPredCount2);
  183.       END;
  184.       Result := NOT Sets.IsEmpty (WithPred);
  185.       Sets.ReleaseSet (WithoutPred);
  186.       Sets.ReleaseSet (WithPred);
  187.       ReleaseArray (PredCountPtr, PredCountSize, TSIZE (SHORTCARD));
  188.       RETURN Result;
  189.    END IsCyclic;
  190.  
  191. PROCEDURE gPredCount    (e: CARDINAL);
  192.    BEGIN
  193.       INC (PredCountPtr^[e]);
  194.    END gPredCount;
  195.  
  196. PROCEDURE gPredCount2    (e: CARDINAL);
  197.    BEGIN
  198.       DEC (PredCountPtr^[e]);
  199.       IF PredCountPtr^[e] = 0 THEN Sets.Include (WithoutPred, e); END;
  200.    END gPredCount2;
  201.  
  202. PROCEDURE GetCyclics    (Rel: tRelation; VAR Set: tSet);
  203.    VAR r    : tRelation;
  204.    BEGIN
  205.       MakeRelation (r, Rel.Size1, Rel.Size2);
  206.       Assign (r, Rel);
  207.       Closure (r);
  208.       Sets.AssignEmpty (Set);
  209.       FOR i := 0 TO r.Size1 DO
  210.      IF Sets.IsElement (i, r.ArrayPtr^[i]) THEN    (* IsReflexive *)
  211.         Sets.Include (Set, i);
  212.      END;
  213.       END;
  214.       ReleaseRelation (r);
  215.    END GetCyclics;
  216.  
  217. PROCEDURE AssignEmpty    (VAR Rel: tRelation);
  218.    BEGIN
  219.       FOR i := 0 TO Rel.Size1 DO
  220.      Sets.AssignEmpty (Rel.ArrayPtr^[i]);
  221.       END;
  222.    END AssignEmpty;
  223.  
  224. PROCEDURE AssignElmt    (VAR Rel: tRelation; e1, e2: INTEGER);
  225.    BEGIN
  226.       AssignEmpty (Rel);
  227.       Include (Rel, e1, e2);
  228.    END AssignElmt;
  229.  
  230. PROCEDURE Assign    (VAR Rel1: tRelation; Rel2: tRelation);
  231.    BEGIN
  232.       FOR i := 0 TO Rel1.Size1 DO
  233.      Sets.Assign (Rel1.ArrayPtr^[i], Rel2.ArrayPtr^[i]);
  234.       END;
  235.    END Assign;
  236.  
  237. PROCEDURE Closure    (VAR Rel: tRelation);
  238.    VAR aj    : tSet;
  239.    BEGIN                (* Warshall *)
  240.       WITH Rel DO
  241.      FOR j := 0 TO Size1 DO
  242.         IF NOT Sets.IsEmpty (ArrayPtr^[j]) THEN
  243.            aj := ArrayPtr^[j];
  244.            FOR i := 0 TO Size1 DO
  245.               IF Sets.IsElement (j, ArrayPtr^[i]) THEN
  246.              Sets.Union (ArrayPtr^[i], aj);
  247.               END;
  248.            END;
  249.         END;
  250.      END;
  251.       END;
  252.    END Closure;
  253.  
  254. PROCEDURE Union        (VAR Rel1: tRelation; Rel2: tRelation);
  255.    BEGIN
  256.       FOR i := 0 TO Rel1.Size1 DO
  257.      Sets.Union (Rel1.ArrayPtr^[i], Rel2.ArrayPtr^[i]);
  258.       END;
  259.    END Union;
  260.  
  261. PROCEDURE Difference    (VAR Rel1: tRelation; Rel2: tRelation);
  262.    BEGIN
  263.       FOR i := 0 TO Rel1.Size1 DO
  264.      Sets.Difference (Rel1.ArrayPtr^[i], Rel2.ArrayPtr^[i]);
  265.       END;
  266.    END Difference;
  267.  
  268. PROCEDURE Intersection    (VAR Rel1: tRelation; Rel2: tRelation);
  269.    BEGIN
  270.       FOR i := 0 TO Rel1.Size1 DO
  271.      Sets.Intersection (Rel1.ArrayPtr^[i], Rel2.ArrayPtr^[i]);
  272.       END;
  273.    END Intersection;
  274.  
  275. PROCEDURE SymDiff    (VAR Rel1: tRelation; Rel2: tRelation);
  276.    BEGIN
  277.       FOR i := 0 TO Rel1.Size1 DO
  278.      Sets.SymDiff (Rel1.ArrayPtr^[i], Rel2.ArrayPtr^[i]);
  279.       END;
  280.    END SymDiff;
  281.  
  282. PROCEDURE Complement    (VAR Rel: tRelation);
  283.    BEGIN
  284.       FOR i := 0 TO Rel.Size1 DO
  285.      Sets.Complement (Rel.ArrayPtr^[i]);
  286.       END;
  287.    END Complement;
  288.  
  289. PROCEDURE IsSubset    (Rel1, Rel2: tRelation): BOOLEAN;
  290.    BEGIN
  291.       FOR i := 0 TO Rel1.Size1 DO
  292.      IF NOT Sets.IsSubset (Rel1.ArrayPtr^[i], Rel2.ArrayPtr^[i]) THEN
  293.         RETURN FALSE;
  294.      END;
  295.       END;
  296.       RETURN TRUE;
  297.    END IsSubset;
  298.  
  299. PROCEDURE IsStrictSubset (Rel1, Rel2: tRelation): BOOLEAN;
  300.    BEGIN
  301.       RETURN IsSubset (Rel1, Rel2) AND IsNotEqual (Rel1, Rel2);
  302.    END IsStrictSubset;
  303.  
  304. PROCEDURE IsEqual    (VAR Rel1, Rel2: tRelation): BOOLEAN;
  305.    BEGIN
  306.       FOR i := 0 TO Rel1.Size1 DO
  307.      IF NOT Sets.IsEqual (Rel1.ArrayPtr^[i], Rel2.ArrayPtr^[i]) THEN
  308.         RETURN FALSE;
  309.      END;
  310.       END;
  311.       RETURN TRUE;
  312.    END IsEqual;
  313.  
  314. PROCEDURE IsNotEqual    (Rel1, Rel2: tRelation): BOOLEAN;
  315.    BEGIN
  316.       RETURN NOT IsEqual (Rel1, Rel2);
  317.    END IsNotEqual;
  318.  
  319. PROCEDURE IsEmpty    (Rel: tRelation): BOOLEAN;
  320.    BEGIN
  321.       FOR i := 0 TO Rel.Size1 DO
  322.      IF NOT Sets.IsEmpty (Rel.ArrayPtr^[i]) THEN RETURN FALSE; END;
  323.       END;
  324.       RETURN TRUE;
  325.    END IsEmpty;
  326.  
  327. PROCEDURE Card        (VAR Rel: tRelation): INTEGER;
  328.    VAR n    : INTEGER;
  329.    BEGIN
  330.       n := 0;
  331.       FOR i := 0 TO Rel.Size1 DO
  332.      INC (n, Sets.Card (Rel.ArrayPtr^[i]));
  333.       END;
  334.       RETURN n;
  335.    END Card;
  336.  
  337. PROCEDURE Select    (VAR Rel: tRelation; VAR e1, e2: INTEGER);
  338.    BEGIN
  339.       FOR i := 0 TO Rel.Size1 DO
  340.      IF NOT Sets.IsEmpty (Rel.ArrayPtr^[i]) THEN
  341.         e1 := i;
  342.         e2 := Sets.Select (Rel.ArrayPtr^[i]);
  343.         RETURN;
  344.      END;
  345.       END;
  346.       e1 := 0;
  347.       e2 := 0;
  348.    END Select;
  349.  
  350. PROCEDURE Extract    (VAR Rel: tRelation; VAR e1, e2: INTEGER);
  351.    BEGIN
  352.       Select (Rel, e1, e2);
  353.       Exclude (Rel, e1, e2);
  354.    END Extract;
  355.  
  356. VAR gProc2b    : ProcOfIntIntToBool;
  357.  
  358. PROCEDURE gProc1b (e: CARDINAL): BOOLEAN;
  359.    BEGIN
  360.       RETURN gProc2b (i, e);
  361.    END gProc1b;
  362.  
  363. PROCEDURE Forall    (Rel: tRelation; Proc: ProcOfIntIntToBool): BOOLEAN;
  364.    BEGIN
  365.       gProc2b := Proc;
  366.       FOR i := 0 TO Rel.Size1 DO
  367.      IF NOT Sets.Forall (Rel.ArrayPtr^[i], gProc1b) THEN RETURN FALSE; END;
  368.       END;
  369.       RETURN TRUE;
  370.    END Forall;
  371.  
  372. PROCEDURE Exists    (Rel: tRelation; Proc: ProcOfIntIntToBool): BOOLEAN;
  373.    BEGIN
  374.       gProc2b := Proc;
  375.       FOR i := 0 TO Rel.Size1 DO
  376.      IF Sets.Exists (Rel.ArrayPtr^[i], gProc1b) THEN RETURN TRUE; END;
  377.       END;
  378.       RETURN FALSE;
  379.    END Exists;
  380.  
  381. PROCEDURE Exists1    (Rel: tRelation; Proc: ProcOfIntIntToBool): BOOLEAN;
  382.    VAR n    : INTEGER;
  383.    BEGIN
  384.       n := 0;
  385.       gProc2b := Proc;
  386.       FOR i := 0 TO Rel.Size1 DO
  387.      IF Sets.Exists (Rel.ArrayPtr^[i], gProc1b) THEN INC (n); END;
  388.       END;
  389.       RETURN n = 1;
  390.    END Exists1;
  391.  
  392. VAR gProc2    : ProcOfIntInt;
  393.  
  394. PROCEDURE gProc1 (e: CARDINAL);
  395.    BEGIN
  396.       gProc2 (i, e);
  397.    END gProc1;
  398.  
  399. PROCEDURE ForallDo    (Rel: tRelation; Proc: ProcOfIntInt);
  400.    BEGIN
  401.       gProc2 := Proc;
  402.       FOR i := 0 TO Rel.Size1 DO
  403.      Sets.ForallDo (Rel.ArrayPtr^[i], gProc1);
  404.       END;
  405.    END ForallDo;
  406.  
  407. PROCEDURE ReadRelation    (f: tFile; VAR Rel: tRelation);
  408.    VAR ch    : CHAR;
  409.    BEGIN
  410.       REPEAT
  411.       UNTIL ReadC (f) = '{';
  412.       AssignEmpty (Rel);
  413.       LOOP
  414.      IF ReadC (f) = '}' THEN EXIT; END;
  415.      i := ReadI (f);
  416.      Include (Rel, i, ReadI (f));
  417.          ch := ReadC (f);
  418.       END;
  419.    END ReadRelation;
  420.  
  421. VAR g    : tFile;
  422.  
  423. PROCEDURE WriteRelation    (f: tFile;     Rel: tRelation);
  424.    BEGIN
  425.       g := f;
  426.       WriteC (f, '{');
  427.       ForallDo (Rel, WritePair);
  428.       WriteC (f, '}');
  429.    END WriteRelation;
  430.  
  431. PROCEDURE WritePair    (e1, e2: INTEGER);
  432.    BEGIN
  433.       WriteC (g, ' ');
  434.       WriteI (g, e1, 1);
  435.       WriteC (g, ' ');
  436.       WriteI (g, e2, 1);
  437.       WriteC (g, ',');
  438.    END WritePair;
  439.  
  440. END Relations.
  441.